#include "XML/XmlPaletteLoader.h"
#include "Xml/XmlSerializer.h"
#include <string>

namespace ECS
{

	std::map<std::string, MetaClass*> XMLPaletteLoader::_defClasses;

	ECS::XMLSerializer xmlSerializer;

	ECS::ComponentDef* XMLPaletteLoader::parseComponent( MetaClass* c, MetaClass* table, TiXmlElement* componentElement )
	{
		void* def = xmlSerializer.readFromXml(componentElement, table);

		auto result = new ECS::ComponentDef(c, table, def);
		return result;
	}

	ECS::ComponentDef* XMLPaletteLoader::ParseComponent( TiXmlElement* componentElement )
	{
		std::string name = componentElement->Value();
		auto it = _defClasses.find(name);

		if (it != _defClasses.end())
		{
			MetaClass* c = MetaClass::getMetaClass(it->first.c_str());
			return parseComponent(c, it->second, componentElement);
		}
		else
			return nullptr;
	}

	AssemblyDef* XMLPaletteLoader::ParseAssembly( TiXmlElement* assemblyElement )
	{
		auto def = new  ECS::AssemblyDef(MetaClass::getMetaClass(assemblyElement->Value()));

		TiXmlElement* componentElement = assemblyElement->FirstChildElement();
		while (componentElement)
		{
			auto c = ParseComponent(componentElement);
			if (c != nullptr)
				def->addComponent(c);

			componentElement = componentElement->NextSiblingElement();
		}
		return def;
	}

	void XMLPaletteLoader::Load( ECS::Palette* palette, uint8_t* buf )
	{
		TiXmlDocument document;
		document.Parse((char*)buf);

		TiXmlElement* root = document.RootElement();
		TiXmlElement* objectElement = root->FirstChildElement();
		while (objectElement)
		{
			std::string name = objectElement->Attribute("name");

			auto assembly = ParseAssembly(objectElement);
			if (assembly != nullptr)
				palette->addTemplate(name, assembly);

			objectElement = objectElement->NextSiblingElement();
		}
	}
}